package com.qian.service.ddj.serviceImpl;

import com.qian.api.ddj.model.*;
import com.qian.api.ddj.model.Order;
import com.qian.api.ddj.service.ICashService;
import com.qian.api.ddj.service.IConfigService;
import com.qian.api.ddj.service.IHolidayService;
import com.qian.api.ddj.service.IOrderService;
import com.qian.api.ddj.util.MoneyUtils;
import com.qian.api.ddj.util.RSASignUtils;
import com.qian.api.ddj.util.SignUtils;
import com.qian.service.ddj.dao.BusinessCardRepository;
import com.qian.service.ddj.dao.BusinessRepository;
import com.qian.service.ddj.dao.OrderRepository;
import com.qian.service.ddj.dao.UserRepository;
import com.qian.service.ddj.entity.*;
import com.yaowk.api.common.BaseException;
import com.yaowk.api.common.PageReq;
import com.yaowk.api.common.PageResp;
import com.yaowk.api.utils.HttpUtils;
import com.yaowk.service.common.BaseRepository;
import com.yaowk.service.common.BaseServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.*;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.Date;

@Service

public class OrderServiceImpl extends BaseServiceImpl<Order, DdjOrder, Integer> implements IOrderService {

    private final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Autowired
    private OrderRepository dao;
    @Autowired
    private UserRepository userDao;
    @Autowired
    private ICashService cashService;
    @Autowired
    private BusinessRepository businessDao;
    @Autowired
    private IHolidayService holidayService;
    @Autowired
    private BusinessCardRepository businessCardDao;
    @Autowired
    private IConfigService configService;

    @Override
    protected BaseRepository<DdjOrder, Integer> getDao() {
        return dao;
    }

    @Override
    protected DdjOrder model2Entity(Order model) {
        if (ObjectUtils.isEmpty(model)) {
            return null;
        }
        DdjOrder order = new DdjOrder();
        order.setStatus(model.getStatus());
        order.setOrderNo(model.getOrderNo());
        order.setUpOrderNo(model.getUpOrderNo());
        order.setPayType(model.getPayType());
        order.setRealAmount(model.getRealAmount());
        order.setUserId(model.getUserId());
        order.setOutOrderNo(model.getOutOrderNo());
        order.setNotifyUrl(model.getNotifyUrl());
        order.setBusinessId(model.getBusinessId());
        order.setBody(model.getBody());
        order.setAmount(model.getAmount());
        order.setCreateTime(model.getCreateTime());
        order.setId(model.getId());
        order.setCode(model.getCode());
        order.setPayTime(model.getPayTime());
        order.setAmountFee(model.getAmountFee());
        order.setRemark(model.getRemark());
        order.setPayerIp(model.getPayerIp());
        order.setCodeId(model.getCodeId());
        return order;
    }

    @Override
    protected Order entity2model(DdjOrder entity) {
        if (ObjectUtils.isEmpty(entity)) {
            return null;
        }
        Order order = new Order();
        order.setStatus(entity.getStatus());
        order.setOrderNo(entity.getOrderNo());
        order.setUpOrderNo(entity.getUpOrderNo());
        order.setPayType(entity.getPayType());
        order.setRealAmount(entity.getRealAmount());
        order.setUserId(entity.getUserId());
        order.setOutOrderNo(entity.getOutOrderNo());
        order.setNotifyUrl(entity.getNotifyUrl());
        order.setBusinessId(entity.getBusinessId());
        order.setBody(entity.getBody());
        order.setAmount(entity.getAmount());
        order.setAmountFee(entity.getAmountFee());
        order.setCreateTime(entity.getCreateTime());
        order.setId(entity.getId());
        order.setCode(entity.getCode());
        order.setPayTime(entity.getPayTime());
        order.setRemark(entity.getRemark());
        order.setSettlementT0(entity.getSettlementT0());
        order.setSettlementT1(entity.getSettlementT1());
        order.setSettlementD0(entity.getSettlementD0());
        order.setSettlementD1(entity.getSettlementD1());
        order.setSettlementFee(entity.getSettlementFee());
        order.setCodeId(entity.getCodeId());
        order.setPayerIp(entity.getPayerIp());
        return order;
    }

    @Override
    @Transactional
    public void orderFinish(Order order) {
        DdjOrder ddjOrder = dao.findOne(order.getId());
        // 订单之前是待支付状态
        if (ddjOrder.getStatus().equals(StatusDict.WAIT_PAY)) {
            if (isNotEmpty(order.getUpOrderNo())) {
                ddjOrder.setUpOrderNo(order.getUpOrderNo());
            }
            ddjOrder.setStatus(StatusDict.SUCCESS_PAY);
            ddjOrder.setPayTime(new Date());
            DdjBusiness ddjBusiness = businessDao.findOne(ddjOrder.getBusinessId());
            DdjBusinessGroup ddjBusinessGroup = ddjBusiness.getBusinessGroup();

            BigDecimal zero = new BigDecimal(0);
            BigDecimal hundred = new BigDecimal(100);
            BigDecimal amount = new BigDecimal(0);

            // t0 立即到账
            if (ddjBusinessGroup.getT0().compareTo(zero) > 0 && !holidayService.verifyHoliday(ddjOrder.getPayTime()) && ddjBusinessGroup.getLazyTime() == 0) {
                amount = amount.add(ddjOrder.getRealAmount().multiply(ddjBusinessGroup.getT0().divide(hundred)));
                ddjOrder.setSettlementT0(StatusDict.NORMAL);
            }

            if (ddjBusinessGroup.getD0().compareTo(zero) > 0) {
                ddjOrder.setSettlementD0(StatusDict.NORMAL);
            }

            if (amount.compareTo(zero) > 0) {
                amount = amount.subtract(ddjOrder.getAmountFee());
                ddjOrder.setSettlementFee(StatusDict.NORMAL);
            }

            // 结算余额
            if (amount.compareTo(zero) > 0) {
                int result = userDao.increaseBalance(ddjOrder.getUserId(), amount);
                if (result != 1) {
                    throw new BaseException("用户余额结算失败");
                }
                result = businessDao.increaseBalance(ddjOrder.getBusinessId(), amount);
                if (result != 1) {
                    throw new BaseException("商户余额结算失败");
                }
                DdjBusinessCard ddjBusinessCard = ddjBusiness.getBusinessCard();
                if (isNotEmpty(ddjBusinessCard)) {
                    result = businessCardDao.increaseBalance(ddjBusinessCard.getId(), amount);
                    if (result != 1) {
                        throw new BaseException("银行卡余额结算失败");
                    }
                }
            }
            if (isSettlementFinish(ddjBusinessGroup, ddjOrder)) {
                ddjOrder.setStatus(StatusDict.SETTLEMENT);
            }

            dao.save(ddjOrder);

            // 自动提现
//        if (ddjUser.getIsAutoCash().equals(StatusDict.NORMAL)) {
//            ddjUser = userDao.findOne(ddjOrder.getUserId());
//            if (ddjUser.getBalance().compareTo(ddjUser.getAutoCashBalance()) >= 0) {
//                Cash cash = new Cash();
//                cash.setCardNo(ddjUser.getCardNo());
//                cash.setCardPerson(ddjUser.getCardPerson());
//                cash.setCardPhone(ddjUser.getCardPhone());
//                cash.setTotal(ddjUser.getAutoCashBalance());
//                cash.setUserId(ddjUser.getId());
//                cashService.cash(cash);
//            }
//        }
//
//        // 提现提示
//        if (ddjUser.getIsSend().equals(StatusDict.NORMAL)) {
//            ddjUser = userDao.findOne(ddjOrder.getUserId());
//            if (ddjUser.getBalance().compareTo(ddjUser.getNotifyBalance()) >= 0) {
//                DdjUser ddjUser1 = new DdjUser();
//                ddjUser1.setId(ddjUser.getId());
//                ddjUser1.setNotifyBalance(ddjUser.getNotifyBalance().add(ddjUser.getNotifyCycle()));
//                userDao.save(ddjUser1);
//                // 发送提示
////                YunbaUtils.publishAlias("尊敬的客户，为了您的资金安全，您该申请提现了。", ddjOrder.getUserId().toString());
//            }
//        }
        }
    }

    private boolean isSettlementFinish(DdjBusinessGroup ddjBusinessGroup, DdjOrder ddjOrder) {
        BigDecimal zero = new BigDecimal(0);
        if (ddjBusinessGroup.getT0().compareTo(zero) > 0 && ddjOrder.getSettlementT0().equals(StatusDict.DELETE)) {
            return false;
        }

        if (ddjBusinessGroup.getD0().compareTo(zero) > 0 && ddjOrder.getSettlementD0().equals(StatusDict.DELETE)) {
            return false;
        }

        if (ddjBusinessGroup.getT1().compareTo(zero) > 0 && ddjOrder.getSettlementT1().equals(StatusDict.DELETE)) {
            return false;
        }

        if (ddjBusinessGroup.getD1().compareTo(zero) > 0 && ddjOrder.getSettlementD1().equals(StatusDict.DELETE)) {
            return false;
        }
        return true;
    }


    @Override
    public String notifyToUser(Order order) {
        try {
            logger.info("notifyToUser");
            DdjOrder ddjOrder = dao.findOne(order.getId());
            if (ddjOrder.getStatus().equals(StatusDict.WAIT_PAY) || ddjOrder.getStatus().equals(StatusDict.NORMAL)) {
                logger.info("NOTIFY FALSE OF WAIT_PAY OR NORMAL");
                throw new BaseException("FALSE");
            }
            DdjUser user = userDao.findOne(ddjOrder.getUserId());
            String amount = MoneyUtils.formatMoney(ddjOrder.getAmount());
            Map<String, String> map = new TreeMap<>();
            map.put("amount", amount);
            map.put("outOrderNo", ddjOrder.getOutOrderNo());
            map.put("orderNo",ddjOrder.getOrderNo());
            if (!StringUtils.isEmpty(ddjOrder.getBody())) {
                map.put("other", ddjOrder.getBody());
            }
            DdjUser ddjUser = userDao.findOne(ddjOrder.getUserId());

            List<String> successList = new ArrayList<>();
            successList.add("166001");
            successList.add("166003");
            if (ddjUser != null && successList.contains(ddjUser.getUsername())) {
                map.put("status", "success");
            }
            Config config = new Config();
            config.setName(ConfigDict.privateKey);
            config = configService.findOne(config);
            String sign = RSASignUtils.sign(SignUtils.getSignParam(map).getBytes(),config.getValue());
            sign = sign.replaceAll("\\+","%2B");

            map.put("sign", sign);
            logger.info("notify = " + ddjOrder.getNotifyUrl());
            String body = SignUtils.params(map);
            logger.info("notify = " + body);
            String receive = HttpUtils.post(ddjOrder.getNotifyUrl(), body);
            if ("SUCCESS".equalsIgnoreCase(receive) && !ddjOrder.getStatus().equals(StatusDict.SETTLEMENT)) {
                ddjOrder.setStatus(StatusDict.FINISH_PAY);
                dao.save(ddjOrder);
            }
            return receive;
        } catch (Exception e) {
            e.printStackTrace();
            logger.info(e.getMessage());
            return "";
        }
    }

    @Override
    public PageResp<Order> findAll(final OrderQueryModel model, PageReq pageReq) {
        PageRequest pageRequest = new PageRequest(pageReq.getPageNumber() - 1, pageReq.getPageSize(), new Sort(Sort.Direction.DESC, "createTime"));
        Long bt = System.currentTimeMillis();
        Page<DdjOrder> page = dao.findAll(new Specification<DdjOrder>() {
            @Override
            public Predicate toPredicate(Root<DdjOrder> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<Date> timePath = root.get("createTime");
                Path<Byte> statusPath = root.get("status");
                Predicate condition = criteriaBuilder.isNotNull(root.<Integer>get("id"));
                // 比较支付金额
                if (isNotEmpty(model.getRealMoney())) {
                    condition = criteriaBuilder.and(condition, criteriaBuilder.equal(root.get("realAmount"), model.getRealMoney()));
                }
                // 比较备注
                if (isNotEmpty(model.getRemark())) {
                    condition = criteriaBuilder.and(condition, criteriaBuilder.equal(root.get("remark"), model.getRemark()));
                }
                // 用户比较
                if (isNotEmpty(model.getUserId()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.equal(root.<Integer>get("userId"), model.getUserId()));
                // 状态比较
                if (isNotEmpty(model.getStatus()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.equal(statusPath, model.getStatus()));
                // 日期比较
                if (isNotEmpty(model.getBeginTime()) && isNotEmpty(model.getEndTime()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.between(timePath, model.getBeginTime(), model.getEndTime()));
                else if (isNotEmpty(model.getBeginTime()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.greaterThanOrEqualTo(timePath, model.getBeginTime()));
                else if (isNotEmpty(model.getEndTime()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.lessThanOrEqualTo(timePath, model.getEndTime()));
                // 支付类型比较
                if (isNotEmpty(model.getPayType()))
                    if (model.getPayType().equals(new Byte("100"))) {
                        condition = criteriaBuilder.and(root.<Byte>get("payType").in(PayTypeDict.ALI_CODE, PayTypeDict.ALI_WAP));
                    } else {
                        condition = criteriaBuilder.and(condition, criteriaBuilder.equal(root.<Byte>get("payType"), model.getPayType()));
                    }
                // 商户比较
                if (isNotEmpty(model.getBusinessId()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.equal(root.<Integer>get("businessId"), model.getBusinessId()));
                // 平台订单号比较
                if (isNotEmpty(model.getOrderNo()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.equal(root.<String>get("orderNo"), model.getOrderNo()));
                // 上游订单号比较
                if (isNotEmpty(model.getUpOrderNo()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.equal(root.<String>get("upOrderNo"), model.getUpOrderNo()));
                // 下游客户订单号比较
                if (isNotEmpty(model.getOutOrderNo()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.equal(root.<String>get("outOrderNo"), model.getOutOrderNo()));
                return condition;
            }
        }, pageRequest);
        Long et = System.currentTimeMillis();
        logger.info("find order Time {}", et - bt);

        PageResp<Order> pageResp = page2pageResp(page);
        for (Order order : pageResp.getList()) {
            DdjUser user = userDao.findOne(order.getUserId());
            order.setUsername(user.getUsername());
            if (isNotEmpty(order.getBusinessId())) {
                DdjBusiness ddjBusiness = businessDao.findOne(order.getBusinessId());
                order.setBusinessName(ddjBusiness.getName());
            }
        }

        logger.info("manager order Time {}", System.currentTimeMillis() - et);
        return pageResp;
    }

    @Override
    @Transactional

    public void settlement(final Integer userId) {
        Calendar nowTime = Calendar.getInstance(); // 当前时间
        Integer hours = nowTime.get(Calendar.HOUR_OF_DAY); // 当前小时
        boolean holiDay = holidayService.verifyHoliday(nowTime.getTime()); // 今日是否节假日

        // 获取今日凌晨
        final Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        final Date endTime = calendar.getTime();

        BigDecimal zero = new BigDecimal(0);
        BigDecimal hundred = new BigDecimal(100);
        BigDecimal totalAmount = new BigDecimal(0);

        // 查询所有应结算的订单
        List<DdjOrder> orders = dao.findAll(new Specification<DdjOrder>() {
            @Override
            public Predicate toPredicate(Root<DdjOrder> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate predicate1 = root.<Byte>get("status").in(StatusDict.SUCCESS_PAY, StatusDict.FINISH_PAY);
                Predicate predicate2 = criteriaBuilder.equal(root.<Integer>get("userId"), userId);
                Predicate predicate4 = criteriaBuilder.lessThan(root.<Date>get("payTime"), endTime);
                return criteriaBuilder.and(predicate1, predicate2, predicate4);
            }
        });

        // 计算结算额度
        for (DdjOrder order : orders) {
            DdjBusiness business = businessDao.findOne(order.getBusinessId());
            DdjBusinessGroup ddjBusinessGroup = business.getBusinessGroup();

            BigDecimal amount = new BigDecimal(0);

            // t0结算
            if (order.getSettlementT0().equals(StatusDict.DELETE) && ddjBusinessGroup.getT0().compareTo(zero) > 0 && !holiDay) {
                if (ddjBusinessGroup.getLazyTime() > 0) {
                    Calendar calendar1 = Calendar.getInstance();
                    calendar1.setTime(order.getPayTime());
                    calendar1.add(Calendar.HOUR_OF_DAY, ddjBusinessGroup.getLazyTime());
                    if (calendar1.compareTo(nowTime) <= 0) {
                        amount = amount.add(order.getRealAmount().multiply(ddjBusinessGroup.getT0().divide(hundred)));
                        order.setSettlementT0(StatusDict.NORMAL);
                    }
                }
            }

            // t1 d1 判断是否结算点
            if (amount.compareTo(zero) == 0 && !ddjBusinessGroup.getSettlementTime().equals(hours)) {
                continue;
            }

            // t1结算
            if (order.getSettlementT1().equals(StatusDict.DELETE) && ddjBusinessGroup.getT1().compareTo(zero) > 0 && !holiDay) {
                if (ddjBusinessGroup.getSettlementTime() <= hours) {
                    amount = amount.add(order.getRealAmount().multiply(ddjBusinessGroup.getT1().divide(hundred)));
                    order.setSettlementT1(StatusDict.NORMAL);
                }
            }

            // d1结算
            if (order.getSettlementD1().equals(StatusDict.DELETE) && ddjBusinessGroup.getD1().compareTo(zero) > 0 && !holiDay) {
                if (ddjBusinessGroup.getSettlementTime() <= hours) {
                    amount = amount.add(order.getRealAmount().multiply(ddjBusinessGroup.getD0().divide(hundred)));
                    order.setSettlementD0(StatusDict.NORMAL);
                }
            }

            // 判断是否需要扣费率
            if (order.getSettlementFee().equals(StatusDict.DELETE) && amount.compareTo(zero) > 0) {
                amount = amount.subtract(order.getAmountFee());
                order.setSettlementFee(StatusDict.NORMAL);
            }

            totalAmount = totalAmount.add(amount);

            if (amount.compareTo(zero) > 0) {
                int result = businessDao.increaseBalance(order.getBusinessId(), amount);
                if (result != 1) {
                    throw new BaseException("商户余额增长失败");
                }
                DdjBusinessCard ddjBusinessCard = business.getBusinessCard();
                if (isNotEmpty(ddjBusinessCard)) {
                    result = businessCardDao.increaseBalance(ddjBusinessCard.getId(), amount);
                    if (result != 1) {
                        throw new BaseException("银行卡余额增长失败");
                    }
                }
            }

            if (isSettlementFinish(ddjBusinessGroup, order)) {
                order.setStatus(StatusDict.SETTLEMENT);
            }

            dao.save(order);
        }

        if (totalAmount.compareTo(zero) > 0) {
            int result = userDao.increaseBalance(userId, totalAmount);
            if (result != 1) {
                throw new BaseException("增加余额出错");
            }
        }
    }

    @Override
    public Order findByOrderNo(String orderNo) {
        Order order = new Order();
        order.setOrderNo(orderNo);
        return super.findOne(order);
    }

    @Override
    public Order findByCode(String code) {
        Order order = new Order();
        List<DdjOrder> lists = dao.QueryOrderByCode(code);
        for (DdjOrder ddjOrder:lists){
            order = entity2model(ddjOrder);
        }
        return order;
    }

    @Override
    public BigDecimal countLockMoneyByUserId(Integer userId) {
        List<DdjOrder> ddjOrders = dao.findAll(new Specification<DdjOrder>() {
            @Override
            public Predicate toPredicate(Root<DdjOrder> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                Predicate predicate = root.get("status").in(StatusDict.FINISH_PAY, StatusDict.SUCCESS_PAY);
                predicate = criteriaBuilder.and(predicate, criteriaBuilder.equal(root.get("userId"), userId));
                return predicate;
            }
        });

        BigDecimal h = new BigDecimal(100);
        BigDecimal lockMoney = new BigDecimal(0);
        Map<Integer, DdjBusinessGroup> groupMap = new HashMap<>();
        for (DdjOrder ddjOrder : ddjOrders) {
            if (!groupMap.containsKey(ddjOrder.getBusinessId())) {
                groupMap.put(ddjOrder.getBusinessId(), businessDao.findOne(ddjOrder.getBusinessId()).getBusinessGroup());
            }
            DdjBusinessGroup ddjBusinessGroup = groupMap.get(ddjOrder.getBusinessId());
            if (ddjOrder.getSettlementD0().equals(StatusDict.DELETE)) {
                lockMoney.add(ddjOrder.getRealAmount().multiply(ddjBusinessGroup.getD0()).divide(h));
            }
            if (ddjOrder.getSettlementD1().equals(StatusDict.DELETE)) {
                lockMoney.add(ddjOrder.getRealAmount().multiply(ddjBusinessGroup.getD1()).divide(h));
            }
            if (ddjOrder.getSettlementT0().equals(StatusDict.DELETE)) {
                lockMoney.add(ddjOrder.getRealAmount().multiply(ddjBusinessGroup.getT0()).divide(h));
            }
            if (ddjOrder.getSettlementT1().equals(StatusDict.DELETE)) {
                lockMoney.add(ddjOrder.getRealAmount().multiply(ddjBusinessGroup.getT1()).divide(h));
            }
        }
        return lockMoney;
    }

    @Override
    public List<CountResultModel> count(final CountModel model) {
        // 按照条件查询到数据
        List<DdjOrder> ddjOrders = dao.findAll(new Specification<DdjOrder>() {
            @Override
            public Predicate toPredicate(Root<DdjOrder> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<Date> timePath = root.get("createTime");
                Predicate condition = root.get("status").in(StatusDict.SUCCESS_PAY, StatusDict.FINISH_PAY, StatusDict.SETTLEMENT);
                // 日期比较
                if (isNotEmpty(model.getBeginTime()) && isNotEmpty(model.getEndTime()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.between(timePath, model.getBeginTime(), model.getEndTime()));
                else if (isNotEmpty(model.getBeginTime()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.greaterThanOrEqualTo(timePath, model.getBeginTime()));
                else if (isNotEmpty(model.getEndTime()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.lessThanOrEqualTo(timePath, model.getEndTime()));
                if (isNotEmpty(model.getPayType()))
                    condition = criteriaBuilder.and(condition, criteriaBuilder.equal(root.<Byte>get("payType"), model.getPayType()));
                return condition;
            }
        });
        Map<String, CountResultModel> map = new HashMap<>();
        for (DdjOrder ddjOrder : ddjOrders) {
            DdjBusiness ddjBusiness = businessDao.findOne(ddjOrder.getBusinessId());
            DdjBusinessCard ddjBusinessCard = ddjBusiness.getBusinessCard();
            if (isNotEmpty(ddjBusinessCard)) {
                String key = ddjBusinessCard.getCardNo();
                if (!map.containsKey(key)) {
                    CountResultModel countResultModel = new CountResultModel();
                    countResultModel.setCardNo(key);
                    map.put(key, countResultModel);
                }
                CountResultModel countResultModel = map.get(key);
                countResultModel.setTotalMoney(countResultModel.getTotalMoney().add(ddjOrder.getRealAmount().subtract(ddjOrder.getAmountFee())));
            }
        }
        List<CountResultModel> list = new ArrayList<>();
        for (String key : map.keySet()) {
            list.add(map.get(key));
        }
        return list;
    }

    @Override
    public Order save(Order model) {
        if (model.isNew()) {
            model = simpleSave(model);
        } else {
            DdjOrder ddjOrder = dao.findOne(model.getId());
            if (isNotEmpty(model.getPayType())) {
                ddjOrder.setPayType(model.getPayType());
            }
            if (isNotEmpty(model.getAmount())) {
                ddjOrder.setAmount(model.getAmount());
            }
            if (isNotEmpty(model.getStatus())) {
                ddjOrder.setStatus(model.getStatus());
            }
            if (isNotEmpty(model.getUserId())) {
                ddjOrder.setUserId(model.getUserId());
            }
            if (isNotEmpty(model.getBody())) {
                ddjOrder.setBody(model.getBody());
            }
            if (isNotEmpty(model.getBusinessId())) {
                ddjOrder.setBusinessId(model.getBusinessId());
                // 计算费率
                DdjBusiness ddjBusiness = businessDao.findOne(model.getBusinessId());
                DdjBusinessGroup ddjBusinessGroup = ddjBusiness.getBusinessGroup();
                BigDecimal tariff = ddjBusinessGroup.tariff(ddjOrder.getPayType());
                ddjOrder.setAmountFee(ddjOrder.getRealAmount().multiply(tariff.divide(new BigDecimal(100))));
            }
            if (isNotEmpty(model.getOutOrderNo())) {
                ddjOrder.setOutOrderNo(model.getOutOrderNo());
            }
            if (isNotEmpty(model.getNotifyUrl())) {
                ddjOrder.setNotifyUrl(model.getNotifyUrl());
            }
            if (isNotEmpty(model.getOrderNo())) {
                ddjOrder.setOrderNo(model.getOrderNo());
            }
            if (isNotEmpty(model.getCode())) {
                ddjOrder.setCode(model.getCode());
            }
            if (isNotEmpty(model.getRealAmount())) {
                ddjOrder.setRealAmount(model.getRealAmount());
            }
            if (isNotEmpty(model.getUpOrderNo())) {
                ddjOrder.setUpOrderNo(model.getUpOrderNo());
            }
            if (isNotEmpty(model.getPayTime())) {
                ddjOrder.setPayType(model.getPayType());
            }
            if (isNotEmpty(model.getRemark()))
                ddjOrder.setRemark(model.getRemark());
            if (isNotEmpty(model.getCodeId()))
                ddjOrder.setCodeId(model.getCodeId());
            model = entity2model(dao.save(ddjOrder));
        }
        return model;
    }
}
